package com.sas.web.panel.articles;

import java.io.Serializable;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Iterator;
import java.util.List;

import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeModel;

import org.apache.wicket.Page;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.markup.html.tree.BaseTree;
import org.apache.wicket.markup.html.tree.ITreeStateListener;
import org.apache.wicket.markup.html.tree.LinkTree;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.LoadableDetachableModel;
import org.apache.wicket.spring.injection.annot.SpringBean;

import com.sas.domain.ArticleField;
import com.sas.model.EntityModel;
import com.sas.repository.ArticleFieldRepository;
import com.sas.web.articles.ArticlesPageListener;


public class ArticleFieldTreePanel extends Panel {

	
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	private IModel<ArticleField> selectedArticleField;
	
	@SpringBean
	private ArticleFieldRepository articleFieldRepository;

	private Class<?> responseClass;

	public ArticleFieldTreePanel(String id) {
		super(id);
//		TreeModel tm = createArticleFieldTreeModel();
		
		IModel<TreeModel> iTreeModel = new LoadableDetachableModel<TreeModel>() {

			/**
			 * 
			 */
			private static final long serialVersionUID = -7688949542312471494L;

			@Override
			protected TreeModel load() {
				return createArticleFieldTreeModel();
			}
		};
		
		BaseTree tree = new LinkTree("articleFieldTree", iTreeModel);
		ITreeStateListener itl = new ArticlesPageListener();		
		tree.getTreeState().addTreeStateListener(itl);
		tree.setRootLess(true);
		add(tree);
	}

	public ArticleFieldTreePanel(String id, Class<?> responseClass) {
		super(id);
		this.responseClass = responseClass;
		TreeModel tm = createArticleFieldTreeModel();
		BaseTree tree = new LinkTree("articleFieldTree", tm);
		tree.getTreeState().addTreeStateListener(new MyListener());
		tree.setRootLess(true);
		add(tree);
	}

	private TreeModel createArticleFieldTreeModel() {
		List<ArticleField> rootList = articleFieldRepository.findRoots();
		
		
		TreeModel model = null;
        DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode();
        addTree(rootNode, rootList.iterator());
        model = new DefaultTreeModel(rootNode);
        
        setSelectedArticleField(new EntityModel<ArticleField>(ArticleField.class, rootList.get(0)));
		return model;
	}
	
	private void addTree(DefaultMutableTreeNode parent, Iterator<ArticleField> it){
		while (it.hasNext()) {
			ArticleField root = it.next();
			Iterator<ArticleField> childs = root.getSubArticleFields().iterator();
			if (childs.hasNext()) {
				DefaultMutableTreeNode childNode = new DefaultMutableTreeNode(root);
				parent.add(childNode);
				addTree(childNode, childs);
			} else {
				parent.add(new DefaultMutableTreeNode(root));
			}
		}
    }

	public void setSelectedArticleField(IModel<ArticleField> imodelArticleField) {
		this.selectedArticleField = imodelArticleField;
	}

	public IModel<ArticleField> getSelectedArticleField() {
		return selectedArticleField;
	}
	
	private class MyListener implements ITreeStateListener, Serializable{

		/**
		 * 
		 */
		private static final long serialVersionUID = 1L;

		@Override
		public void allNodesCollapsed() {
			
		}

		@Override
		public void allNodesExpanded() {
			
		}

		@Override
		public void nodeCollapsed(Object node) {

		}

		@Override
		public void nodeExpanded(Object node) {
			
		}

		@Override
		public void nodeSelected(Object node) {
			DefaultMutableTreeNode aux = (DefaultMutableTreeNode) node;
			ArticleField ret = (ArticleField) aux.getUserObject();
			setSelectedArticleField(new EntityModel<ArticleField>(ArticleField.class, ret));
			
			try {
				Constructor responsePageConstructor = responseClass.getConstructor(ArticleFieldTreePanel.class);
				setResponsePage((Page) responsePageConstructor.newInstance(ArticleFieldTreePanel.this));
			} catch (SecurityException e) {
				throw new IllegalAccessError(e.getMessage());
			} catch (NoSuchMethodException e) {
				throw new IllegalAccessError(e.getMessage());
			} catch (IllegalArgumentException e) {
				throw new IllegalAccessError(e.getMessage());
			} catch (InstantiationException e) {
				throw new IllegalAccessError(e.getMessage());
			} catch (IllegalAccessException e) {
				throw new IllegalAccessError(e.getMessage());
			} catch (InvocationTargetException e) {
				throw new IllegalAccessError(e.getMessage());
			}
		}

		@Override
		public void nodeUnselected(Object node) {
			
		}		
	}

}
